
import * as cc from "cc";
import { StringFunction } from "../../utils/StringFunction";
// import { StringFunction } from "../../utils/js-extension";
import { VMI18NLabelAdapter } from "../i18n/VMI18NLabelAdapter";
import { VMEntity, VMLabelAttr } from "../VMEntity";
import { VM } from "../VMMgr";

declare let CC_EDITOR;

export class VMLabelEntity extends VMEntity{
   
    observerAttr: VMLabelAttr;
    originText: string;
    
    //保存着字符模板格式的数组 (只会影响显示参数)
    templateFormatArr: string[] = [];
    i18nAdapter: VMI18NLabelAdapter = null;
    onValueInit() {
        if(CC_EDITOR){
            return;
        }
        if(!this.originText){
            //// 多语言适配
            // let i18nAdapter = this.component.node.getComponent(VMI18NLabelAdapter);
            // if(i18nAdapter){
            //     i18nAdapter.vmLabelEntity = this;
            //     this.originText = i18nAdapter.getLocalizedOriginText();
            //     this.i18nAdapter = i18nAdapter;
            // }else{
            //     this.originText = this.getValue();
            // }
            this.originText = this.getValue();
        }
        this.parseTemplate();
        this.updateValue();
    }
    onStart() {
        if(CC_EDITOR){
            return;
        }
    }

    updateValue(){
        
        let _watchPath = this.observerAttr.watchPath;
        if(this.observerAttr.templateMode){
            // 如果监听的是两个值，则必定是用的模板模式
            if(!Array.isArray(_watchPath)){
                _watchPath = [_watchPath];
            }
            let max = _watchPath.length;
            for (let i = 0; i < max; i++) {
                let val0 = VM.getValue(_watchPath[i], '?');
                // 单数据路径
                let val = this.formatValue(val0,'',_watchPath[i]);
                this.templateValuesCache[i] = val;
            }
            this.setValue(this.getFormatText(this.templateValuesCache)); // 重新解析
        }else{
            if(Array.isArray(_watchPath)){
                let max = _watchPath.length;
                for (let i = 0; i < max; i++) {
                    let val = VM.getValue(_watchPath[i],'?');
                    this.templateValuesCache[i] = val;
                }
                // 多数据路径
                let val = this.formatValue(this.templateValuesCache,'',_watchPath); // 重新解析
                this.setValue(this.getFormatText(val));
            }else{
                let val0 = VM.getValue(_watchPath as string);
                let val = this.formatValue(val0,'',_watchPath);
                this.setValue(this.getFormatText(val));
            }

        }
    }

    onValueChanged(newValue: any, oldValue: any, pathArr: readonly string[]) {
        if(CC_EDITOR){
            return;
        }
        let self = this;
        let _watchPath = this.observerAttr.watchPath;
        let vmTween = this.observerAttr.vmTween as IVMTween;

         let _updateParamsByLabelEntity = (params)=> {
             if(!Array.isArray(params)){
                params = [params];
             }
            this.i18nAdapter && this.i18nAdapter.updateParamsByLabelEntity(params);
         }

        if(this.observerAttr.templateMode){    
            if(!Array.isArray(_watchPath)){
                _watchPath = [_watchPath];
            }
            let path = pathArr.join('.');
            //寻找缓存位置
            let index = _watchPath.findIndex(v => v === path);
            if (index >= 0) {
                
                let _resolve = (_newValue: any,_oldValue: any,_path: any)=>{
                    // 单数据 路径
                    let val = self.formatValue(_newValue,_oldValue,_path);
                    self.templateValuesCache[index] = val; //缓存值
                    _updateParamsByLabelEntity(self.templateValuesCache);
                    self.setValue(self.getFormatText(self.templateValuesCache)); // 重新解析文本
                }

                if(vmTween){
                    vmTween.onTransition(newValue,oldValue,path,_resolve);
                }else{
                    _resolve(newValue,oldValue,path);
                }
            }
        }else{
            let _resolve = (_newValue: any,_oldValue: any,_path: any)=>{
                let val = self.formatValue(_newValue,_oldValue,_path); // 重新解析
                _updateParamsByLabelEntity(val);
                self.setValue(self.getFormatText(val));
            }

            if(Array.isArray(_watchPath)){
                
                let _oldVal = [...this.templateValuesCache];

                let path = pathArr.join('.');
                //寻找缓存位置
                let index = _watchPath.findIndex(v => v === path);
                if (index >= 0) {
                    //如果是所属的路径，就可以替换文本了
                    this.templateValuesCache[index] = newValue; //缓存值
                }

                if(vmTween){
                    vmTween.onTransition(this.templateValuesCache,_oldVal,_watchPath,_resolve);
                }else{
                    _resolve(this.templateValuesCache,_oldVal,path);
                }
            }else{

                if(vmTween){
                    vmTween.onTransition(newValue,oldValue,_watchPath,_resolve);
                }else{
                    _resolve(newValue,oldValue,_watchPath);
                }
            }
        }
    }

    formatValue(newValue,oldValue,watchPath){
        if(this.observerAttr.formator){
            return this.observerAttr.formator.call(this.controllerUserComponent,{
                entity: this,
                newValue,
                oldValue,
                watchPath,
                node: this.node,
                nodeIdx: 0
            });
        }
        return newValue;
    }

    //解析模板 获取初始格式化字符串格式 的信息
    parseTemplate() {
        let regexAll = /\{(.+?)\}/g; //匹配： 所有的{value}
        let regex = /\{(.+?)\}/;//匹配： {value} 中的 value
        let res = this.originText.match(regexAll);//匹配结果数组
        if (res == null) return;
        for (let i = 0; i < res.length; i++) {
            const e = res[i];
            let arr = e.match(regex);
            let matchName = arr[1];
            //let paramIndex = parseInt(matchName)||0;
            let matchInfo = matchName.split(':')[1] || '';
            this.templateFormatArr[i] = matchInfo;

            // 这里不再自动设置为 模板模式
            // if(matchInfo != ''){
            //     this.observerAttr.templateMode = true;
            // }
        }
    }

    getFormatText(value){
        if(!this.originText){
            return '';
        }
        if(!Array.isArray(value)){
            value = [value];
        }
        // let _string = this.originText;
        // _string = _string.format.apply(_string,value);
        let _string = this.stringFormat(this.originText,...value);
        return _string;
    }
    stringFormat(key,...args){        
        let result = key;


        if(args.length){
            let regexAll = /\{(.+?)\}/g;  ////这个在索引大于9时会有问题
            let resRegexAllArr = result.match(regexAll);
            if(!resRegexAllArr){
                return result;
            }
            let regex = /\{(.+?)\}/;
            for (let i = 0; i < resRegexAllArr.length; i++) {
                const e = resRegexAllArr[i];
                let arr = e.match(regex); //匹配到的数组 [{{value}}, value]
                let indexNum = parseInt(arr[1] || '0') || 0; //取出数组的 value 元素 转换成整数
                let matchName = arr[1];

                // 只能进行一次 格式化 {0:int}
                // let matchInfo = matchName.split(':')[1] || '';
                // let v = StringFunction.deal(args[indexNum],matchInfo);

                let v = args[indexNum];
                let matchInfos = matchName.split(':');
                if(!matchInfos){
                    matchInfos = "";
                }else{
                    for (let j = 1; j < matchInfos.length; j++) {
                        const matchInfo = matchInfos[j];
                        v = StringFunction.deal(v,matchInfo);
                    }
                }
                result = result.replace(e, v);
            }
        }
        return result;
    }

    setValue(value: string){
        if(this.component instanceof cc.Label || this.component instanceof cc.RichText || this.component instanceof cc.EditBox){
            this.component.string = value;
        }
    }

    getValue(): string {
        if(this.component instanceof cc.Label || this.component instanceof cc.RichText || this.component instanceof cc.EditBox){
            return this.component.string;
        }
        return '';
    }

    changeOriginText(value){
        this.originText = value;
        this.updateValue();
    }

    onBind() {
        if(CC_EDITOR){
            return;
        }        
    }
    onUnBind() {  
        if(CC_EDITOR){
            return;
        }      
    }
    onCheckProperty(){
        return 'string' in this.component;
    }
}

